/**
 * Student Name: Philippe Gambling
 * Course: CSCI 5733
 * Section: 01
 * Student Number: 0603418
 * Assignment: Homework 2
 * Requirements: http://dcm.uhcl.edu/yue/courses/xml/summer2009/hw/h2.html
 * Filename: UniqueNamePathDepthSax.java
 * Descriptions: Counts the maximum unique element names in a single path using the SAX API.
 * 
 */

import java.io.File;
import java.util.HashSet;
import java.util.Stack;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * @author Philippe Gambling
 *
 */
public class UniqueNamePathDepthSax extends DefaultHandler {

	/**
	 * @param args
	 */
	public static void main(String[] argv) {
        if (argv.length != 1) {
            System.err.println("Usage: UniqueNamePathDepthSax filename");
            System.exit(1);
        }
	
        String filename = argv[0];
        
        // Use an instance of ourselves as the SAX event handler
        UniqueNamePathDepthSax handler = new UniqueNamePathDepthSax();
        // Use the default (non-validating) parser
        SAXParserFactory factory = SAXParserFactory.newInstance();

        try {
            SAXParser saxParser = factory.newSAXParser();
            saxParser.parse(new File(argv [0]), handler);

        } catch (Throwable t) {
            t.printStackTrace();
        }
        
        System.out.println("The maximum number of distinct element names in the paths in " 
        		           + filename + " is " + numUnique + ".");
	}

	// Data Members
	private static int numUnique = 0;
	private Stack<String> elementsInPath = new Stack<String>();
	
	// Handler Methods
	@Override
	public void endElement(String uri, 
						   String localName, 
						   String qName)
			throws SAXException {
		// At end of path, count number of unique elements in stack
		// and store in numUnique if greater than its current value.
		int numUniqueInPath = (new HashSet<String>(elementsInPath)).size();
		numUnique = (numUniqueInPath>numUnique) ? numUniqueInPath:numUnique;
		elementsInPath.pop(); // Back up stack to previous element in this path
	}

	@Override
	public void startElement(String uri, 
							 String localName, 
							 String qName,
							 Attributes attributes) 
			throws SAXException {
		elementsInPath.push(qName);
	}

}
